package com.example.ormsqlsplicingframe1.orm.wrapper;

import java.text.SimpleDateFormat;
import java.util.*;

public class Where {
    private Map<String,Object> params = new HashMap<>();

    private List<Object> values = new ArrayList<>();

    private boolean isAnd = true;

    private boolean whetherExecuteNew = false;

    //是否用执行器
    public Where whetherExecuteNew(){
        whetherExecuteNew = true;
        return this;
    }

    private List<String> list = new ArrayList<>();

    public Where eq(String column,Object value){

            values.add(value);
            value = "?";
            if (list != null &&list.size()>0){
                if (isAnd){
                    list.add(" and "+column+" = "+value+" ");
                }else {
                    list.add(" or "+column+" = "+value+" ");
                }
            }else {
                list.add(" "+column+" =  "+value+" ");
            }

        return this;
    }

    public List<Object> getValues(){
        return values;
    }

    public Where not(String column,Object value){

        //params.put(column,obj);

            values.add(value);
            value = " ? ";
            if (list != null &&list.size()>0){
                if (isAnd){
                    list.add(" and "+column+" !=  "+value+" ");
                }else {
                    list.add(" or "+column+" !=  "+value+" ");
                }
            }else {
                list.add(" "+column+" !=  "+value+" ");
            }




        return this;
    }

    public Where orSome(Map<String,Object> map){

        StringBuilder stringBuilder = new StringBuilder();

        stringBuilder.append(" and ( ");
        int a =0;
        for ( String row : map.keySet()) {

            //值
            Object o = map.get(row);
            values.add(o);
            o =" ? ";
            if (a >0){
                if (isAnd){
                    stringBuilder.append(" and "+row+" =  '"+o+"' ");
                }else {
                    stringBuilder.append(" or "+row+" =  '"+o+"' ");
                }

            }else {
                stringBuilder.append(" "+row+" =  '"+o+"' ");
            }
            a++;
        }

        stringBuilder.append(" ) ");

        list.add(stringBuilder.toString());

        return this;
    }

    private List<String> orSomeList = new ArrayList<>();

    private boolean orIsAnd = true;

    public Where orSome(String column,Object value){


        if (orSomeList != null && orSomeList.size()>0){
            values.add(value);
            value = " ? ";
            if (isAnd){
                orSomeList.add(" and "+column+" =  '"+value+"' ");
            }else {
                orSomeList.add(" or "+column+" =  '"+value+"' ");
            }
        }else {
            orSomeList.add(" ("+column+" =  '"+value+"' ");
        }

        return this;
    }

    public Where isSomeOr(){
        this.orIsAnd = false;
        return this;
    }
    public Where isSomeAnd(){
        this.orIsAnd = true;
        return this;
    }

    public Where in(String column,SelectWrapper select){
        String sql = select.getSql();
        String newsql = sql.replaceAll(sql.substring(sql.indexOf("select") + 6, sql.indexOf("from") - 1)," "+ column);
        list.add(" and "+column+" in ("+newsql+")");
        return this;
    }
    public Where in(String column,Long[] value){

        StringBuilder builder = new StringBuilder();

        isAndOr(builder,column);
        int a=0;

        for (final Long aLong : value) {
            if (a>0){
                builder.append(" , ");
            }

            values.add(aLong);
            builder.append(" ? ");

            a++;
        }

        list.add(builder.append(")").toString());


        return this;
    }

    public Where in(String column,List<Long> value){

        StringBuilder builder = new StringBuilder();

        isAndOr(builder,column);
        int a=0;

        for (final Long aLong : value) {
            if (a>0){
                builder.append(" , ");
            }

                values.add(aLong);
                builder.append(" ? ");


            a++;
        }

        list.add(builder.append(")").toString());


        return this;
    }

    private void isAndOr(StringBuilder builder,String column){
        if (list != null && list.size()>0){
            if (isAnd){
                builder.append(" and "+column+" in (");
            }else {
                builder.append(" or "+column+" in (");
            }

        }else {
            builder.append(column+" in (");
        }
    }

    public Where in(Object column,List<String> value){

        StringBuilder builder = new StringBuilder();
        int a=0;
        isAndOr(builder,column.toString());
        for (final String aLong : value) {
            if (a>0){
                builder.append(" , ");
            }

                values.add(aLong);
                builder.append(" ? ");

            a++;
        }

        list.add(builder.append(")").toString());


        return this;
    }

    public Where in(String column,String[] value){

        StringBuilder builder = new StringBuilder();

        isAndOr(builder,column);
        int a=0;

        for (final String aLong : value) {
            if (a>0){
                builder.append(" , ");
            }

                values.add(aLong);
                builder.append(" ? ");

            a++;
        }

        list.add(builder.append(")").toString());


        return this;
    }

    public Where in(Object column,String... value){

        StringBuilder builder = new StringBuilder();

        isAndOr(builder,column.toString());
        int a=0;

        for (final String aLong : value) {
            if (a>0){
                builder.append(" , ");
            }

                values.add(aLong);
                builder.append(" ? ");

            a++;
        }

        list.add(builder.append(")").toString());


        return this;
    }

    /**
     * 时间范围查询
     * @param startTime  时间字段
     * @param startDate  开始时间
     * @param endDate    结束时间
     * @return
     */
    public Where dateFORMAT(String startTime , Date startDate,Date endDate){

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");


            if (list!= null && list.size()>0){
                String date = "and "+ startTime +" BETWEEN  ?  AND ? " ;
                list.add(date);
                values.add(format.format(startDate)+" 00:00:00");
                values.add(format.format(endDate)+" 23:59:59");
            }else {
                String date =  startTime +" BETWEEN  ?  AND  ? " ;
                list.add(date);
                values.add(format.format(startDate)+" 00:00:00");
                values.add(format.format(endDate)+" 23:59:59");
            }

        return this;
    }


    /**
     *  查询传进来的当天时间
     * @param startTime  查询的字段
     * @param startDate  查询时间
     * @return
     */
    public Where dateFORMAT(String startTime , Date startDate){

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        if (whetherExecuteNew){
            if (list!= null && list.size()>0){

                String date = "and  DATE_FORMAT("+startTime+",'%Y-%m-%d') = "+" DATE_FORMAT(? , '%Y-%m-%d' )";
                list.add(date);
                values.add(format.format(startDate));
            }else {
                String date = " DATE_FORMAT("+startTime+",'%Y-%m-%d') = "+" DATE_FORMAT(? , '%Y-%m-%d' )";
                list.add(date);
                values.add(format.format(startDate));
            }
        }else {
            if (list!= null && list.size()>0){
                // DATE_FORMAT(create_time, '%Y-%m-%d') = DATE_FORMAT('2023-02-09', '%Y-%m-%d')
                String date = "and  DATE_FORMAT("+startTime+",'%Y-%m-%d') = "+" DATE_FORMAT('"+format.format(startDate)+"' , '%Y-%m-%d' )";
                list.add(date);
            }else {
                String date = " DATE_FORMAT("+startTime+",'%Y-%m-%d') = "+" DATE_FORMAT('"+format.format(startDate)+"' , '%Y-%m-%d' )";
                //String date =  startTime +" BETWEEN ' "+format.format(startDate) +" 00:00:00' AND '"+format.format(endDate) +" 23:59:59'" ;
                list.add(date);
            }
        }


        return this;
    }

    public Where in(String column,String value){

        StringBuilder builder = new StringBuilder();

        if (whetherExecuteNew){
            builder.append(column+" in (");
            int a =0;
            for (String s : value.split(",")) {
                if (a >0){
                    builder.append(",");
                }
                values.add(s);
                builder.append(" ? ");
                a++;
            }
        }else {
            builder.append(column+" in ("+value);
        }

        list.add(builder.append(")").toString());


        return this;
    }

    public Where rightLike(String column ,Object value){

        value = temporary(value);


            if (list != null &&list.size()>0){
                values.add(value);
                value = " ? ";
                if (isAnd){
                    list.add(" and "+column+"  like '%'"+value+" ");
                }else {
                    list.add(" or "+column+" like  '%'"+value+" ");
                }

            }else {
                values.add(value);
                value = " ? ";
                list.add(" "+column+" like  '%'"+value+" ");
            }


        return this;
    }

    public Where  leftLike(String column ,Object value){

        value = temporary(value);


            if (list != null &&list.size()>0){
                values.add(value);
                value = " ? ";
                if (isAnd){
                    list.add(" and "+column+" like  "+value+"'%' ");
                }else {
                    list.add(" or "+column+" like  "+value+"'%' ");
                }

            }else {
                values.add(value);
                value = " ? ";
                list.add(" "+column+" like  "+value+"'%' ");
            }


        return this;
    }

    private Object temporary(Object value) {
        if (value instanceof String){
            String string = value.toString();

            String temporary = string.replaceAll("'","’");

            value =  temporary.replaceAll("\\\\", "、");
        }

        return value;
    }

    public Where overallLike(String column ,Object value){

        value = temporary(value);

        if (list != null &&list.size()>0){
                values.add(value);
                value = " ? ";
               if (isAnd){
                    list.add(" and "+column+" like  '%'"+value+"'%' ");
               }else {
                    list.add(" or "+column+" like  '%'"+value+"'%' ");
                }

            }else {
                values.add(value);
                value = " ? ";
                list.add(" "+column+" like  '%'"+value+"'%' ");
            }

        return this;
    }


    public Where or(){
        this.isAnd = false;
        return this;
    }

    public Where and(){
        this.isAnd = true;
        return this;
    }


    public String getSql(){
        StringBuilder builder = new StringBuilder();

        if (list!= null && list.size()>0){
            for (final String s : list) {
                builder.append(s);
            }
            int a = 0;
            if (orSomeList != null && orSomeList.size()>0){
                for (final String s : orSomeList) {
                    if (a ==0){
                        if (isAnd){
                            builder.append(" and ");
                        }else{
                            builder.append(" or ");
                        }
                    }
                    builder.append(s);
                    a++;
                }
                builder.append(" ) ");
            }
        }else {
            if (orSomeList != null && orSomeList.size()>0){
                for (final String s : orSomeList) {
                    builder.append(s);
                }
                builder.append(" ) ");
            }
        }


        return builder.toString();

    }

    public Map getParams(){
        return params;
    }
}
